﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Grafos;

namespace GrafosTestUnit {
    /// <summary>
    /// Testes na classe Vértice
    /// </summary>
    [TestClass]
    public class TesteVértice {

        /// <summary>
        /// Testa se as comparações de igualdade (através do método Equals) funcionam corretamente
        /// </summary>
        /// <remarks>
        /// Processo:
        /// Cria os vértices V1..V4
        /// Define V1, V2 e V3 como novos vértices
        /// V1 e V2 tem todas suas propriedades igualadas
        /// V4 recebe o endereço de V3
        /// Verifica-se:
        /// V1 é diferente de V2
        /// V3 é igual a V4
        /// </remarks>
        [TestMethod]
        public void IgualdadeEntreVértices() {
            Vértice v1, v2, v3, v4;
            
            v1 = new Vértice("V");
            v2 = new Vértice("V");
            v1.λ = v2.λ = 0;
            v1.π = v2.π = null;
            v1.Tag = v2.Tag = null;

            Assert.AreNotEqual(v1, v2);

            v3 = new Vértice("V3");
            v4 = v3;

            Assert.AreEqual(v3, v4);
        }

        /// <summary>
        /// Verifica se dois vértices ficam devidamente conectados ao criar-se uma aresta
        /// </summary>
        /// <remarks>
        /// Cria os vértices V1 e V2
        /// Cria a aresta A=(V1, V2)
        /// Verifica-se:
        /// V1 possui uma aresta
        /// V2 possui uma aresta
        /// </remarks>
        [TestMethod]
        public void ConectarVértices() {
            Vértice v1, v2;
            Aresta a;
            
            v1 = new Vértice("C");
            v2 = new Vértice("D");
            a = new Aresta(v1, v2);

            Assert.AreEqual(1, v1.GetArestas().Count);
            Assert.AreEqual(1, v2.GetArestas().Count);
        }

        /// <summary>
        /// Verifica se o grau do vértice é calculado corretamente
        /// </summary>
        /// <remarks>
        /// Cria os vértices V1..V5
        /// Cria as arestas A1..A6
        /// Define-se as arestas:
        /// A1: V1-V2
        /// A2: V2-V3
        /// A3: V3-V4
        /// A4: V2-V5
        /// A5: V3-V5
        /// A6: V4-V4
        /// Verifica-se:
        /// O grau de V1 é 1
        /// O grau de V2 é 3
        /// O grau de V3 é 3
        /// O grau de V4 é 3
        /// O grau de V5 é 2
        /// </remarks>
        [TestMethod]
        public void GrauVértice() {
            Vértice v1, v2, v3, v4, v5;
            Aresta a1, a2, a3, a4, a5, a6;

            v1 = new Vértice("1");
            v2 = new Vértice("2");
            v3 = new Vértice("3");
            v4 = new Vértice("4");
            v5 = new Vértice("5");

            a1 = new Aresta(v1, v2);
            a2 = new Aresta(v2, v3);
            a3 = new Aresta(v3, v4);
            a4 = new Aresta(v2, v5);
            a5 = new Aresta(v3, v5);
            a6 = new Aresta(v4, v4);

            Assert.AreEqual(1, v1.Grau());
            Assert.AreEqual(3, v2.Grau());
            Assert.AreEqual(3, v3.Grau());
            Assert.AreEqual(3, v4.Grau());
            Assert.AreEqual(2, v5.Grau());
        }
        
        /// <summary>
        /// Verifica se a vizinhança do vértice é determinada corretamente
        /// </summary>
        /// <remarks>
        /// Cria os vértices V1..V5
        /// Cria as arestas A1..A6
        /// Define-se as arestas:
        /// A1: V1-V2
        /// A2: V2-3
        /// A3: V3-V4
        /// A4: V4-V4
        /// A5: V2-V5
        /// A6: V2-V5
        /// Verifica-se:
        /// V1 possui 1 vizinho
        /// V2 é o único vizinho de V1
        /// V2 possui 3 vizinhos
        /// Os vizinhos de V2 são V1, V3 e V5
        /// V3 possui 2 vizinhos
        /// Os vizinhos de V3 são V2 e V4
        /// V4 possui 1 vizinho
        /// V3 está na vizinhança de V4
        /// V4 não está na vizinhança de V4
        /// V5 tem 1 vizinho
        /// V2 é o único vizinho de V5
        /// </remarks>
        [TestMethod]
        public void VizinhançaVértice() {
            Vértice v1, v2, v3, v4, v5;
            Aresta a1, a2, a3, a4, a5, a6;

            v1 = new Vértice("6");
            v2 = new Vértice("7");
            v3 = new Vértice("8");
            v4 = new Vértice("9");
            v5 = new Vértice("10");

            a1 = new Aresta(v1, v2);
            a2 = new Aresta(v2, v3);
            a3 = new Aresta(v3, v4);
            a5 = new Aresta(v2, v5);
            a6 = new Aresta(v2, v5);
            a4 = new Aresta(v4, v4);

            Assert.AreEqual(1, v1.Vizinhança().Count);
            Assert.AreEqual(v2, v1.Vizinhança()[0]);

            Assert.AreEqual(3, v2.Vizinhança().Count);
            Assert.IsTrue(v2.Vizinhança().Contains(v1));
            Assert.IsTrue(v2.Vizinhança().Contains(v3));
            Assert.IsTrue(v2.Vizinhança().Contains(v5));

            Assert.AreEqual(2, v3.Vizinhança().Count);
            Assert.IsTrue(v3.Vizinhança().Contains(v2));
            Assert.IsTrue(v3.Vizinhança().Contains(v4));

            Assert.AreEqual(1, v4.Vizinhança().Count);
            Assert.IsTrue(v4.Vizinhança().Contains(v3));
            Assert.IsFalse(v4.Vizinhança().Contains(v4));

            Assert.AreEqual(1, v5.Vizinhança().Count);
            Assert.IsTrue(v5.Vizinhança().Contains(v2));
        }

        /// <summary>
        /// Testa o método que procura uma aresta entre dois vértices
        /// </summary>
        /// <remarks>
        /// Processo:
        /// Cria os vértices V1, V2 e V3
        /// Cria as arestas A1=(V1, V2), A2=(V2, V3)
        /// Verifica-se que ao procurar uma aresta:
        /// De V1 a V2, encontra-se A1
        /// De V2 a V1, encontra-se A1
        /// De V2 a V3, encontra-se A2
        /// De V3 a V2, encontra-se A2
        /// De V1 a V3, encontra-se NULL
        /// De V3 a V1, encontra-se NULL
        /// </remarks>
        [TestMethod]
        public void ProcurarAresta() {
            Vértice v1, v2, v3;
            Aresta a1, a2;

            v1 = new Vértice("v1");
            v2 = new Vértice("v2");
            v3 = new Vértice("v3");

            a1 = new Aresta(v1, v2);
            a2 = new Aresta(v2, v3);

            Assert.AreEqual(a1, v1.ProcurarAresta(v2));
            Assert.AreEqual(a1, v2.ProcurarAresta(v1));
            Assert.AreEqual(a2, v2.ProcurarAresta(v3));
            Assert.AreEqual(a2, v3.ProcurarAresta(v2));
            Assert.IsNull(v1.ProcurarAresta(v3));
            Assert.IsNull(v3.ProcurarAresta(v1));
        }

        /// <summary>
        /// Testa o método que lista todas as arestas entre dois vértices
        /// </summary>
        /// <remarks>
        /// Processo:
        /// Cria os vértices V1, V2 e V3
        /// Cria as arestas A1=(V1, V2), A2=(V1, V2), A3=(V2, V3)
        /// Verifica-se:
        /// Existem duas arestas de V1 a V2
        /// Existem 0 arestas de V1 a V3
        /// Existem 2 arestas de V2 a V1
        /// Existe 1 aresta de V2 a V3
        /// Existem 0 arestas de V3 a V1
        /// Existe 1 aresta de V3 a V2
        /// </remarks>
        [TestMethod]
        public void ProcurarArestas() {
            Vértice v1, v2, v3;
            Aresta a1, a2, a3;

            v1 = new Vértice("Nome1");
            v2 = new Vértice("Nome2");
            v3 = new Vértice("Nome3");

            a1 = new Aresta(v1, v2);
            a2 = new Aresta(v1, v2);
            a3 = new Aresta(v2, v3);

            Assert.AreEqual(2, v1.ProcurarArestas(v2).Count);
            Assert.AreEqual(0, v1.ProcurarArestas(v3).Count);
            Assert.AreEqual(2, v2.ProcurarArestas(v1).Count);
            Assert.AreEqual(1, v2.ProcurarArestas(v3).Count);
            Assert.AreEqual(0, v3.ProcurarArestas(v1).Count);
            Assert.AreEqual(1, v3.ProcurarArestas(v2).Count);
        }
    }
}
